package com.lcz.licence.controller;

import com.lcz.licence.entity.AdditionInfo;
import com.lcz.licence.entity.LicenseCreatorParam;
import com.lcz.licence.serverinfo.AbstractServerInfos;
import com.lcz.licence.serverinfo.LinuxServerInfos;
import com.lcz.licence.serverinfo.WindowsServerInfos;
import com.lcz.licence.util.LicenseCreator;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * @author lcz
 * @desc 许可证控制者
 * @mail lcz_0130@163.com
 * @date 2025/07/21
 */
@RestController
@RequestMapping("/license")
public class LicenseController {

    @Value("${license.keystore.path}")
    String keyStorePath;

    /**
     * 获取服务器硬件信息
     */
    @GetMapping("/getServerInfos")
    public AdditionInfo getServerInfos(String osName) {
        // 操作系统类型
        if (StringUtils.isBlank(osName)) {
            osName = System.getProperty("os.name");
        }
        osName = osName.toLowerCase();

        AbstractServerInfos abstractServerInfos;

        // 根据不同操作系统类型选择不同的数据获取方法
        if (osName.startsWith("windows")) {
            abstractServerInfos = new WindowsServerInfos();
        } else if (osName.startsWith("linux")) {
            abstractServerInfos = new LinuxServerInfos();
        } else {
            // 其他服务器类型
            abstractServerInfos = new LinuxServerInfos();
        }

        return abstractServerInfos.getServerInfos();
    }

    /**
     * 生成证书
     */
    @PostMapping("/generateLicense")
    public Map<String, Object> generateLicense(@RequestBody LicenseCreatorParam param) {
        Map<String, Object> resultMap = new HashMap<>(2);
        param.setLicensePath(keyStorePath + "license.lic");
        param.setPrivateKeysStorePath(keyStorePath + "privateKeys.keystore");
        param.setPublicKeysStorePath(keyStorePath + "publicCerts.keystore");
        param.setPublicKeysStorePath(keyStorePath + "publicCerts.keystore");
        File file = new File(keyStorePath);
        if (!file.exists()) {
            file.mkdirs();
        }
        boolean result;
        try {
            LicenseCreator licenseCreator = new LicenseCreator(param);
            result = licenseCreator.generateLicense();
            if (result) {
                resultMap.put("code", "200");
                resultMap.put("msg", "证书文件生成成功！");
            } else {
                resultMap.put("code", "401");
                resultMap.put("msg", "证书文件生成失败,请检查配置信息是否正确");
            }
        } catch (Exception e) {
            resultMap.put("code", "401");
            resultMap.put("msg", e.getMessage());
        }
        return resultMap;
    }

    /**
     * 下载证书及其公钥文件
     */
    @GetMapping("/download")
    public void downloadFile(@RequestParam("file") String fileName, HttpServletResponse response) throws IOException {
        if (fileName == null || fileName.isEmpty()) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "文件名不能为空");
            return;
        }
        if (!"license.lic".equals(fileName) && !"publicCerts.keystore".equals(fileName)) {
            response.sendError(HttpServletResponse.SC_FORBIDDEN, "不允许下载的文件");
            return;
        }
        File file = new File(keyStorePath + fileName);
        if (!file.exists()) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND, "文件不存在");
            return;
        }
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
        try (FileInputStream fis = new FileInputStream(file);
             OutputStream os = response.getOutputStream()) {
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
        } catch (IOException e) {
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "文件下载失败");
        }
    }

}
